home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / dev / c / RConfig.lha / RConfig_v1.1 / rlib / rlib_alloca.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-13  |  3.9 KB  |  195 lines

  1. /*
  2.  * rlib.c   v1.3
  3.  * ~~~~~~
  4.  *   Copyright (C) 1992 by Anthon Pang, Omni Communications Products.
  5.  *
  6.  *   Replacement library for:
  7.  *     - alloca.a68
  8.  */
  9.  
  10. /*
  11.  * alloca()
  12.  */
  13. #ifdef __ALLOCA_REPLACE
  14.  
  15. #if defined(__SAFE_ALLOCA) && defined(__RISKY_ALLOCA)
  16. #error "Conflicting alloca() flags--{SAFE, RISKY}"
  17. #endif
  18.  
  19. #if !defined(__SAFE_ALLOCA) && !defined(__RISKY_ALLOCA)
  20. #error "Missing alloca() flag--{SAFE, RISKY}"
  21. #endif
  22.  
  23. #ifdef __SETJMP_REPLACE
  24. #asm
  25.     dseg
  26.     global  __last_alloca_blk,4     ; chain the alloca()'d blocks
  27. #endasm
  28. #endif
  29.  
  30. #asm
  31.     xref    _malloc
  32.     xref    _free
  33.  
  34.     cseg
  35.  
  36. ; ``stub()'' - cleanup--free temp. block, and restore program counter
  37. ;
  38. ; scratch registers: <none>
  39.  
  40.     ds.w    0   ; word align this
  41.  
  42. blockstart set *
  43. blockstart2:
  44. rtsvector:
  45.     dc.l    0   ; original return address
  46. #endasm
  47.  
  48. #ifdef __SETJMP_REPLACE
  49. #asm
  50. prevblock:
  51.     dc.l    0   ; ptr to previous allocated block
  52. #endasm
  53. #endif
  54.  
  55. #asm
  56. codestart set *
  57. codestart2:
  58. #endasm
  59.  
  60. #ifdef __SETJMP_REPLACE
  61. #asm
  62.     move.l  prevblock(pc),__last_alloca_blk     ; unlink
  63. #endasm
  64. #endif
  65.  
  66. #asm
  67.     move.l  rtsvector(pc),-(a7)
  68.     movem.l d0/d1,-(a7)         ; save return values
  69.  
  70.     pea     blockstart2(pc)
  71.  
  72.     ; kludge, as ``far code'' doesn't prevent jmp->bra optimization
  73.     dc.b    $4e,$f9     ; jmp <absolute>
  74.     dc.l    freea
  75.  
  76. blockend set *
  77.  
  78. ; constants
  79. ;   size of block to copy (in bytes)
  80. blocksize   set blockend-blockstart
  81. codesize    set blockend-codestart
  82.  
  83. ; _alloca
  84. ;
  85. ; scratch registers: d0/a0-a1
  86. ;
  87. #endasm
  88.  
  89. #ifdef __RISKY_ALLOCA
  90. #asm
  91.     public  _alloca
  92.  
  93. _alloca
  94.     moveq   #blocksize,d0
  95.     add.l   4(sp),d0        ; add the block size to allocate
  96. #endasm
  97. #else ; __SAFE_ALLOCA
  98. #asm
  99.     public  __alloca
  100.  
  101. __alloca
  102.     moveq   #blocksize,d0
  103.     add.l   8(sp),d0        ; add the block size to allocate
  104. #endasm
  105. #endif
  106.  
  107. #asm
  108.     move.l  d0,-(sp)
  109.  
  110.     jsr     _malloc
  111.  
  112.     tst.l   d0
  113.     beq.s   alloca_exit     ; branch if unable to alloc memory
  114.  
  115.     move.l  d0,a0           ; a0 = start of temp. block
  116. #endasm
  117.  
  118. #ifdef __RISKY_ALLOCA
  119. #asm
  120.     move.l  4(a5),(a0)+     ; copy the return address above the stack frame
  121.                             ;   to the temp. block
  122. #endasm
  123. #ifdef __SETJMP_REPLACE
  124. #asm
  125.     move.l  __last_alloca_blk,(a0)+     ; link
  126.     move.l  d0,__last_alloca_blk        ; update
  127. #endasm
  128. #endif
  129. #asm
  130.     move.l  a0,4(a5)        ; replace return address with this address (a0)
  131.                             ;   this is where the freea stub is copied
  132. #endasm
  133. #endif
  134.  
  135. #ifdef __SAFE_ALLOCA
  136. #asm
  137. ; compensate for size of temp block on stack, and our proc's return address
  138.  
  139.     move.l  8(sp),a1        ; get pointer to return address
  140.     move.l  (a1),(a0)+      ; copy return address to temp. block
  141.  
  142. #endasm
  143. #ifdef __SETJMP_REPLACE
  144. #asm
  145.     move.l  __last_alloca_blk,(a0)+     ; link
  146.     move.l  d0,__last_alloca_blk        ; update
  147. #endasm
  148. #endif
  149.  
  150. #asm
  151.     move.l  a0,(a1)         ; replace return address with this address (a0)
  152.                             ;   pointer to freea stub
  153. #endasm
  154. #endif
  155.  
  156. #asm
  157.     lea     codestart2(pc),a1
  158.     moveq   #(codesize/2)-1,d0      ; size in words
  159.  
  160. copy_block
  161.     move.w  (a1)+,(a0)+
  162.     dbra    d0,copy_block
  163.  
  164.     movem.l a0/a6,-(sp)
  165.     move.l  $0004,a6
  166.     cmpi.l  #37,$0014(a6)           ; lib_Version
  167.     ble     1$
  168.  
  169.     jsr     -$027c(a6)              ; CacheClearU()     (* v37 *)
  170.  
  171. 1$  movem.l (sp)+,d0/a6
  172.  
  173. alloca_exit
  174.     addq.w  #4,sp           ; pop size off stack (which we pushed for malloc())
  175.     rts
  176.  
  177. ; freea
  178. ;
  179. ;   - we can't touch a7 and we can't have global vars...so we store
  180. ;     information in the temp.block
  181. ;   - a stub is required to access this information
  182. ;   - freea() is also needed since stub can't free the block while it's
  183. ;     running inside
  184. ;
  185. ; scratch registers:
  186.  
  187. freea
  188.     jsr     _free       ; assumes pointer to block is on stack...
  189.     addq.w  #4,a7
  190.     movem.l (sp)+,d0/d1
  191.     rts                 ; ...and the original return address is right above
  192.  
  193. #endasm
  194. #endif /* __ALLOCA_REPLACE */
  195.